//
//  XMLObject.m
//  pa
//
//  Created by HaiJiao Chen on 12-7-19.
//  Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
//

#import "XMLObject.h"
#include <libxml/globals.h>

@interface XMLParser : NSObject
@property (nonatomic, assign) xmlDocPtr doc;
- (id)initWithData:(NSData*)data;
@end
@implementation XMLParser
@synthesize doc;
- (id)initWithData:(NSData*)data
{
    self = [super init];
    if (self)
    {
        doc = xmlParseMemory((const char*)[data bytes], [data length]);
    }
    return self;
}
- (void)dealloc
{
    xmlFreeDoc(doc);
    [super dealloc];
}
@end

@interface XMLObject()
@property (nonatomic, retain) XMLParser* parser;
@property (nonatomic, assign) xmlNodePtr node;
@end

@implementation XMLObject
@synthesize parser;
@synthesize node;

+ (XMLObject*)parse:(NSData*)data
{
    XMLParser* par = [[XMLParser alloc] initWithData:data];
    XMLObject* obj = [[XMLObject alloc] init];
    obj.parser = par;
    obj.node = xmlDocGetRootElement(par.doc);
    [par release];
    return [obj autorelease];
}

- (int)getCount
{
    if (self.node)
    {
        return xmlChildElementCount(self.node);
    }
    return 0;
}

- (NSString*)getName
{
    if (self.node)
    {
        if (self.node->name)
        {
            return [NSString stringWithUTF8String:(const char*)self.node->name];
        }
    }
    return nil;
}

- (XMLObject*)getXMLObjectForKey:(NSString*)key
{
    if (self.node && key)
    {
        const char* _key = [key UTF8String];
        xmlNodePtr cur = self.node->children;
        while (cur)
        {
            if (cur->type == XML_ELEMENT_NODE)
            {
                if (strcmp((const char*)cur->name, _key) == 0)
                {
                    XMLObject* ret = [[XMLObject alloc] init];
                    ret.parser = self.parser;
                    ret.node = cur;
                    return [ret autorelease];
                }
            }
            cur = cur->next;
        }
    }
    return nil;
}

- (XMLObject*)getXMLObjectForIndex:(int)index
{
    if (self.node && index >= 0)
    {
        xmlNodePtr cur = self.node->children;
        while (cur)
        {
            if (cur->type == XML_ELEMENT_NODE)
            {
                if (index-- == 0)
                {
                    XMLObject* ret = [[XMLObject alloc] init];
                    ret.parser = self.parser;
                    ret.node = cur;
                    return [ret autorelease];
                }
            }
            cur = cur->next;
        }
    }
    return nil;
}


- (NSString*)getStringForKey:(NSString*)key defaultValue:(NSString*)val
{
    if (self.node && key)
    {
        const char* _key = [key UTF8String];
        xmlNodePtr cur = self.node->children;
        while (cur)
        {
            if (cur->type == XML_ELEMENT_NODE)
            {
                if (strcmp((const char*)cur->name, _key) == 0)
                {
                    xmlChar* content = xmlNodeListGetString(self.parser.doc, cur->children, 1);
                    NSString* nscontent = val;
                    if (content)
                    {
                        nscontent = [NSString stringWithUTF8String:(const char*)content];
                        xmlFree(content);
                    }
                    return nscontent;
                }
            }
            cur = cur->next;
        }
    }
    return val;

}
- (NSString*)getStringForIndex:(int)index defaultValue:(NSString*)val
{
    if (self.node && index >= 0)
    {
        xmlNodePtr cur = self.node->children;
        while (cur)
        {
            if (cur->type == XML_ELEMENT_NODE)
            {
                if (index-- == 0)
                {
                    xmlChar* content = xmlNodeListGetString(self.parser.doc, cur->children, 1);
                    NSString* nscontent = val;
                    if (content)
                    {
                        nscontent = [NSString stringWithUTF8String:(const char*)content];
                        xmlFree(content);
                        nscontent = [nscontent stringByTrimmingCharactersInSet:
                                     [NSCharacterSet whitespaceAndNewlineCharacterSet]];
                    }
                    return nscontent;
                }
            }
            cur = cur->next;
        }
    }
    return val;
}

- (int)getIntForKey:(NSString*)key defaultValue:(int)val
{
    if (self.node && key)
    {
        const char* _key = [key UTF8String];
        xmlNodePtr cur = self.node->children;
        while (cur)
        {
            if (cur->type == XML_ELEMENT_NODE)
            {
                if (strcmp((const char*)cur->name, _key) == 0)
                {
                    xmlChar* content = xmlNodeListGetString(self.parser.doc, cur->children, 1);
                    int nscontent = val;
                    if (content)
                    {
                        nscontent = atoi((const char*)content);
                        char buffer[256];
                        sprintf(buffer, "%d", nscontent);
                        if (strcmp(buffer, (const char*)content) != 0)
                        {
                            nscontent = val;
                        }
                        xmlFree(content);
                    }
                    return nscontent;
                }
            }
            cur = cur->next;
        }
    }
    return val;
}

- (int)getIntForIndex:(int)index defaultValue:(int)val
{
    if (self.node && index >= 0)
    {
        xmlNodePtr cur = self.node->children;
        while (cur)
        {
            if (cur->type == XML_ELEMENT_NODE)
            {
                if (index-- == 0)
                {
                    xmlChar* content = xmlNodeListGetString(self.parser.doc, cur->children, 1);
                    int nscontent = val;
                    if (content)
                    {
                        nscontent = atoi((const char*)content);
                        char buffer[256];
                        sprintf(buffer, "%d", nscontent);
                        if (strcmp(buffer, (const char*)nscontent) != 0)
                        {
                            nscontent = val;
                        }
                        xmlFree(content);
                    }
                    return nscontent;
                }
            }
            cur = cur->next;
        }
    }
    return val;
}

- (NSMutableDictionary*)convert2Dictionary
{
    NSMutableDictionary* dic = [NSMutableDictionary dictionary];
    int count = [self getCount];
    for (int i = 0; i < count; i++)
    {
        XMLObject* obj = [self getXMLObjectForIndex:i];
        if ([obj getCount] == 0)
        {
            [dic setValue:[self getStringForIndex:i defaultValue:@""] forKey:[obj getName]];
        }
        else
        {
            NSDictionary* sub = [obj convert2Dictionary];
            [dic setValue:sub forKey:[obj getName]];
        }
    }
    return dic;
}

- (NSMutableArray*)convert2Array
{
    NSMutableArray* arr = [NSMutableArray array];
    int count = [self getCount];
    for (int i = 0; i < count; i++)
    {
        XMLObject* obj = [self getXMLObjectForIndex:i];
        if ([obj getCount] > 0)
        {
            NSMutableDictionary* sub = [obj convert2Dictionary];
            [sub setValue:[obj getName] forKey:@"item-key"];
            [arr addObject:sub];
        }
    }
    return arr;
}

@end
